package com.leyou.user.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.leyou.common.constants.LyConstants;
import com.leyou.common.constants.MQConstants;
import com.leyou.common.exception.pojo.ExceptionEnum;
import com.leyou.common.exception.pojo.LyException;
import com.leyou.common.pojo.SmsData;
import com.leyou.user.mapper.UserMapper;
import com.leyou.user.pojo.User;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    /**
     * 校验用户名和手机号唯一性
     */
    public Boolean checkDate(String date, Integer type) {
        //构造条件
        User user = new User();

        //判断类型
        switch (type) {
            case 1:
                user.setUsername(date);
                break;
            case 2:
                user.setPhone(date);
        }

        QueryWrapper<User> queryWrapper = Wrappers.query(user);

        //执行查询返回结果 selectCount查询记录数，没记录返回0 说明用户不存在返回true
        return userMapper.selectCount(queryWrapper) == 0;
    }


    /**
     * 发送短信验证码
     */
    public void sendVerifyCode(String phone) {
        //生成随机验证码
        String code = RandomStringUtils.randomNumeric(6);

        //保存验证码到redis
        redisTemplate.opsForValue().set(LyConstants.REDIS_KEY_PRE+phone,code,5, TimeUnit.MINUTES);

        //把手机号和验证码发送给MQ
        SmsData smsData = new SmsData();
        smsData.setPhone(phone);
        smsData.setCode(code);

        rocketMQTemplate.convertAndSend(MQConstants.Topic.SMS_TOPIC_NAME,smsData);
    }


    /**
     * 用户注册
     */
    public void register(User user, String code) {
        //校验验证码是否存在和正确
        String redisCode = redisTemplate.opsForValue().get(LyConstants.REDIS_KEY_PRE + user.getPhone());
        if (!redisCode.equals(code) || redisCode==null) {
            //验证码不存在或者错误
            throw new LyException(ExceptionEnum.INVALID_VERIFY_CODE);
        }

        try {
            //对密码加盐加密
            user.setPassword(passwordEncoder.encode(user.getPassword()));

            //保存用户数据
            userMapper.insert(user);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }


    /**
     * 校验用户名和密码是否正确
     */
    public User query(String username, String password) {
        //判断用户是否存在
        User user = new User();
        user.setUsername(username);
        QueryWrapper queryWrapper = Wrappers.query(user);

        User loginUser = userMapper.selectOne(queryWrapper);

        if (loginUser==null) {
            throw new LyException(ExceptionEnum.INVALID_USERNAME_PASSWORD);
        }

        //判断密码是否正确
        if (!passwordEncoder.matches(password,loginUser.getPassword())) {
            throw new LyException(ExceptionEnum.INVALID_USERNAME_PASSWORD);
        }

        return loginUser;
    }
}